package com.ewayde.base.statemachine.impl;

import com.ewayde.base.statemachine.Action;
import com.ewayde.base.statemachine.State;
import com.ewayde.base.statemachine.Transition;
import com.ewayde.base.statemachine.Condition;

/**
 * @author yanwei li create  2024-05-28 18:46
 */
public class TransitionImpl<S,E,C> implements Transition<S,E,C> {

    /* 事前状态 */
    private State<S,E,C> sourceState;
    /* 事后状态 */
    private State<S,E,C> targetState;
    /* 事件 */
    private E event;
    /* 条件 */
    private Condition<C> condition;
    /* 事后动作 */
    private Action<S,E,C> action;

    /**
     * 获取当前转换之前的状态
     *
     * @return 转换前的状态
     */
    @Override
    public State<S, E, C> getSourceState() {
        return sourceState;
    }

    /**
     * 设置转换前的状态
     *
     * @param sourceState 转换前的状态
     */
    @Override
    public void setSourceState(State<S, E, C> sourceState) {
        this.sourceState = sourceState;
    }

    /**
     * 获取当前转换发生的事件
     *
     * @return 事件
     */
    @Override
    public E getEvent() {
        return this.event;
    }

    /**
     * 设置转换事件
     *
     * @param event E
     */
    @Override
    public void setEvent(E event) {
        this.event = event;
    }

    /**
     * 获取转换后的状态
     *
     * @return 转换后的状态 target State
     */
    @Override
    public State<S, E, C> getTargetState() {
        return this.targetState;
    }

    /**
     * 设置转换后的状态
     *
     * @param state 转换后的状态 target State
     */
    @Override
    public void setTargetState(State<S, E, C> state) {
        this.targetState = state;
    }

    /**
     * 获取转换完成后执行的动作
     */
    @Override
    public Action<S, E, C> getAction() {
        return this.action;
    }

    /**
     * 设置当前转换后要完成的动作
     *
     * @param action
     */
    @Override
    public void setAction(Action<S, E, C> action) {
        this.action = action;
    }

    /**
     * DO 转换
     *
     * @param ctx 实例
     * @return 转换后的状态
     */
    @Override
    public State<S, E, C> transit(C ctx, boolean checkCondition) {
        verify();

        if (action != null && checkCondition){
            action.execute(sourceState.getId(),targetState.getId(),event,ctx);
        }

        return this.targetState;
    }

    public boolean verify(){

        return true;
    }

    public Condition<C> getCondition() {
        return condition;
    }

    public void setCondition(Condition<C> condition) {
        this.condition = condition;
    }
}
